<?php

namespace p5\objects;

/**
 * Created by PhpStorm.
 * User: simon
 * Date: 2015/11/23
 * Time: 9:53
 */
class ArrayUtils
{
    /**
     * 通过 $myLines 某一行 $myCompareColumn 的值与 $yourLines 中某一行的 $yourCompareColumn 值相等。
     * 将 otherArray 中的字段横向扩展到 myArray 每一行
     * @param $myLines
     * @param $yourLines
     * @param $myCompareColumn
     * @param string $yourCompareColumn
     */
    public static function extend(&$myLines, $yourLines, $myCompareColumn, $yourCompareColumn = "")
    {
        if (empty($yourCompareColumn)) {
            $yourCompareColumn = $myCompareColumn;
        }
        $size = count($myLines);
        for ($i = 0; $i < $size; $i++) {
            $myLine = $myLines[$i];
            $myCompareValue = PropertyUtils::get($myLine, $myCompareColumn);
            for ($t = 0; $t < count($yourLines); $t++) {
                $bean = $yourLines[$t];
                if (!is_array($bean)) {
                    $bean = json_decode(json_encode($bean), true);
                }
                if ($myCompareValue . "" === $bean[$yourCompareColumn] . "") {
                    foreach ($bean as $key => $value) {
                        if (is_array($myLine)) {
                            $myLines[$i][$key] = $value;
                        } else {
                            $myLines[$i]->$key = $value;
                        }
                    }
                }
            }
        }
    }

    public static function splitBySize($list, $size)
    {
        $result = [];
        if (!empty($list)) {
            $offset = 0;
            while (true) {
                $temp = array_slice($list, $offset, $size);
                if (empty($temp)) {
                    break;
                }
                array_push($result, $temp);
                $offset += $size;
            }
        }
        return $result;
    }

    public static function find($list, $key, $value)
    {
        $result = self::find_all($list, $key, $value);
        if (count($result) > 0) {
            return $result[0];
        }
        return null;
    }

    public static function find_all($list, $key, $value)
    {
        $result = [];
        foreach ($list as $line) {
            if (PropertyUtils::getProperty($line, $key) == $value) {
                array_push($result, $line);
            }
        }
        return $result;
    }


    public static function fill_blank(&$matrix, $key, $value)
    {
        if (!array_key_exists($key, $matrix) || empty($matrix[$key])) {
            $matrix[$key] = $value;
        }
    }


    public static function fill_blank_from_request(&$matrix, $keys = array())
    {
        if (empty($keys)) {
            $keys = array_keys(RequestUtils::get_parameters());
        }
        for ($i = 0; $i < count($keys); $i++) {
            self::fill_blank($matrix, $keys[$i], RequestUtils::get($keys[$i]));
        }
    }

    public static function array_mirror(&$m1, $m2)
    {
        $keys = array_keys($m1);
        for ($i = 0; $i < count($keys); $i++) {
            $key = $keys[$i];
            if (array_key_exists($key, $m2)) {
                $m1[$key] = $m2[$key];
            }
        }
        return $m1;
    }

    /**
     * 获得 matrix 中 与元素 element 相对位置为 position 的元素
     * @param $matrix
     * @param $element
     * @param $position
     * @return string
     */
    public static function get_nearby_elements($matrix, $element, $position)
    {
        if (empty($matrix)) {
            return "";
        }
        $size = count($matrix);
        $offset = 0;
        for ($i = 0; $i < $size; $i++) {
            if ($matrix[$i] == $element) {
                $offset = $i + $position;
                $offset = max($offset, 0);
                $offset = $offset % $size;
                break;
            }
        }
        return $matrix[$offset];
    }


    public static function find_elements_with_key_prefix($matrix, $key_prefix)
    {
        $temp = array();
        $keys = array_keys($matrix);
        for ($i = 0; $i < count($keys); $i++) {
            $key = $keys[$i];
            if (substr($key, 0, strlen($key_prefix)) == $key_prefix) {
                $temp[$key] = $matrix[$key];
            }
        }
        return $temp;
    }

    public static function first_not_empty_value($matrix, $keys = array())
    {
        for ($i = 0; $i < count($keys); $i++) {
            $key = $keys[$i];
            if (!array_key_exists($key, $matrix)) {
                continue;
            }
            if (!empty($matrix[$key])) {
                return $matrix[$key];
            }
        }
        return "";
    }

    public static function filter_empty_elements($matrix)
    {
        $temp = array();
        for ($i = 0; $i < count($matrix); $i++) {
            $e = $matrix[$i];
            if (!empty($e)) {
                array_push($temp, $e);
            }
        }
        return $temp;
    }

    public static function patchJuniors($mainArray, $juniorArray, $link_column, $extName)
    {
        $result = [];
        foreach ($mainArray as $line) {
            $line[$extName] = [];
            foreach ($juniorArray as $junior) {
                if ($line[$link_column] != $junior[$link_column]) {
                    continue;
                }
                array_push($line[$extName], $junior);
            }
            array_push($result, $line);
        }
        return $result;
    }

    public static function unsetBlanks(&$array, $keys = [])
    {
        if (empty($keys)) {
            $keys = array_keys($array);
        }
        foreach ($keys as $key) {
            if (array_key_exists($key, $array) && empty($array[$key])) {
                unset($array[$key]);
            }
        }
    }

    public static function fetch($matrix, $index, $defaultValue = "")
    {
        if (empty($matrix) || count($matrix) <= $index) {
            return $defaultValue;
        }
        return $matrix[$index];
    }

    /**
     * 两个数组相加
     * @param $a1
     * @param $a2
     * @param bool|true $filterDuplicates 是否剔除重复的元素
     * @return mixed
     */
    public static function plus($a1, $a2, $filterDuplicates = true)
    {
        $matrix = $a1;
        $size = count($a2);
        for ($i = 0; $i < $size; $i++) {
            $item = $a2[$i];
            if ($filterDuplicates) {
                if (!in_array($item, $matrix)) {
                    array_push($matrix, $item);
                }
            } else {
                array_push($matrix, $item);
            }
        }
        return ($matrix);
    }

    public static function pick($list, $name, $removeDuplidates = false)
    {
        $result = [];
        foreach ($list as $bean) {
            $value = PropertyUtils::getProperty($bean, $name);
            if ($removeDuplidates && in_array($value, $result)) {
                continue;
            }
            array_push($result, $value);
        }
        return $result;
    }

    static public function pushIfAbsent(&$array, $element)
    {
        if (in_array($element, $array)) {
            return;
        }
        array_push($array, $element);
    }

    /**
     * @param $matrix
     * @param $name
     * @param $value
     */
    public static function magicSet(&$matrix, $name, $value)
    {
        $index = strpos($name, ".");
        if ($index === false) {
            $matrix[$name] = $value;
        } else {
            $prefix = substr($name, 0, $index);
            $name = substr($name, $index + 1);
            // echo "<br/> " . $prefix . "/" . $name;
            self::magicSet($matrix[$prefix], $name, $value);
        }
    }

    public static function filter($matrix, $callback)
    {
        $result = [];
        for ($i = 0; $i < count($matrix); $i++) {
            if ($callback($matrix[$i]) === true) {
                array_push($result, $matrix[$i]);
            }
        }
        return $result;
    }

    public static function forceToArray($value)
    {
        if ($value == null) {
            return [];
        }
        if (is_array($value)) {
            return $value;
        }
        if (is_string($value)) {
            return explode(",", $value);
        }
        return [$value];
    }

    public static function sort(&$list, $callback, $asc = true)
    {
        if ($list == null || count($list) < 2) {
            return;
        }
        $size = count($list);
        for ($i = 0; $i < $size - 1; $i++) {
            $line_i = $list[$i];
            for ($j = $i + 1; $j < $size; $j++) {
                $line_j = $list[$j];
                $flag = $callback($line_i, $line_j);
                if (($flag > 0 && $asc === true) || ($flag < 0 && $asc === false)) {
                    $temp = $line_i ;
                    $line_i = $list[$j];
                    $list[$i] = $list[$j];
                    $list[$j] = $temp ;
                    // $line_j = $temp ;
                }
            }
        }
    }

}